﻿//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Microsoft Public License.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace AstoriaOverAstoria
{
    using System;
    using System.Diagnostics;
    using System.Linq.Expressions;

    /// <summary>Class representing a result of expression conversion.</summary>
    internal class ExpressionConversionResult
    {
        /// <summary>The converted expression.</summary>
        private Expression expression;

        /// <summary>The <see cref="IQueryResultsProcessor"/> to be applied to the results.</summary>
        private IQueryResultsProcessor queryResultsProcessor;

        /// <summary>Constructor.</summary>
        /// <param name="expression">The result expression.</param>
        public ExpressionConversionResult(Expression expression)
        {
            this.SetResultExpression(expression);
        }

        /// <summary>Copy constructor</summary>
        /// <param name="source">The original to make a copy from</param>
        public ExpressionConversionResult(ExpressionConversionResult source)
        {
            this.expression = source.expression;
            this.queryResultsProcessor = source.queryResultsProcessor;
        }

        /// <summary>The converted expression.</summary>
        public Expression Expression
        {
            get { return this.expression; }
        }

        /// <summary>The <see cref="IQueryResultsProcessor"/> to be applied to the results.</summary>
        public IQueryResultsProcessor QueryResultsProcessor
        {
            get { return this.queryResultsProcessor; }
        }

        /// <summary>Adds a <see cref="IQueryResultsProcessor"/> to the list of processors to be applied to the results of the query.</summary>
        /// <param name="processor">The processor to add (processors are applied in the order they were added).</param>
        public void AddQueryResultsProcessor(IQueryResultsProcessor processor)
        {
            if (this.queryResultsProcessor == null)
            {
                this.queryResultsProcessor = processor;
            }
            else
            {
                CombiningQueryResultsProcessor combiningQueryResultsProcessor = this.queryResultsProcessor as CombiningQueryResultsProcessor;
                if (combiningQueryResultsProcessor == null)
                {
                    combiningQueryResultsProcessor = new CombiningQueryResultsProcessor();
                    combiningQueryResultsProcessor.AddProcessor(this.queryResultsProcessor);
                    this.queryResultsProcessor = combiningQueryResultsProcessor;
                }

                combiningQueryResultsProcessor.AddProcessor(processor);
            }
        }

        /// <summary>Sets the result expression.</summary>
        /// <param name="expr">The result expression.</param>
        public void SetResultExpression(Expression expr)
        {
            Debug.Assert(expr != null, "expression != null");
            this.expression = expr;
        }
    }
}
